package com.kailong.service.Impl;


import cn.hutool.core.util.IdUtil;
import com.kailong.entity.auth.CaptchaEntity;
import com.kailong.entity.sys.UserConditionEntity;
import com.kailong.entity.sys.UserEntity;
import com.kailong.entity.sys.UserRoleEntity;
import com.kailong.exception.BusinessException;
import com.kailong.helper.IdGenerateHelper;
import com.kailong.helper.TokenHelper;
import com.kailong.mapper.sys.UserRoleMapper;
import com.kailong.util.AssertUtil;
import com.kailong.util.PasswordUtil;
import com.kailong.util.RedisUtil;
import com.kailong.util.TokenUtil;
import com.wf.captcha.ArithmeticCaptcha;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpStatus;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.kailong.dto.PageResultDTO;
import com.kailong.dto.UserSearchDTO;
import com.kailong.entity.auth.AuthUserEntity;
import com.kailong.entity.auth.JwtUserEntity;
import com.kailong.entity.auth.TokenEntity;


import com.kailong.mapper.Usermapper;
import com.kailong.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.transaction.annotation.Transactional;


import javax.servlet.http.HttpServletRequest;
import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;


/**
 * created by kailong on 2025/8/4
 */
@Service
public class UserServiceImpl implements UserService {
    @Autowired
    private Usermapper usermapper;
    @Autowired
    private UserRoleMapper userRoleMapper;
    @Autowired
    private AuthenticationManagerBuilder authenticationManagerBuilder;
    @Autowired
    private TokenHelper tokenHelper;
    @Autowired
    private RedisUtil redisUtil;
    @Autowired
    private PasswordUtil passwordUtil;
    @Autowired
    private IdGenerateHelper idGenerateHelper;
    @Autowired
    private UserDetailsService userDetailsService;
    @Value("${mall.mgt.captchaExpireSecond:60}")
    private int captchaExpireSecond;

    private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(UserServiceImpl.class);
    private static final String CAPTCHA_PREFIX = "captcha:";

    @Override
    public UserEntity fingById(Long id) {
        return usermapper.selectById( id);
    }

    @Override
    @Transactional(rollbackFor = Throwable.class)
    public void insert(UserEntity userEntity) {
        UserConditionEntity userConditionEntity = new UserConditionEntity();
        userConditionEntity.setUserName(userEntity.getUserName());
        AssertUtil.isTrue(CollectionUtils.isEmpty(usermapper.searchByCondition(userConditionEntity)), "用户名称已存在");

        userConditionEntity = new UserConditionEntity();
        userConditionEntity.setEmail(userEntity.getEmail());
        AssertUtil.isTrue(CollectionUtils.isEmpty(usermapper.searchByCondition(userConditionEntity)), "邮箱已存在");

        userEntity.setPassword(passwordUtil.encode(userEntity.getPassword()));
         usermapper.insert(userEntity);

        List<UserRoleEntity> userRoleEntities = buildUserRoleEntityList(userEntity);
        if (CollectionUtils.isNotEmpty(userRoleEntities)) {
            userRoleMapper.batchInsert(userRoleEntities);
        }
    }
    private List<UserRoleEntity> buildUserRoleEntityList(UserEntity userEntity) {
        if (CollectionUtils.isNotEmpty(userEntity.getRoles())) {
            return userEntity.getRoles().stream().map(x -> {
                UserRoleEntity userRoleEntity = new UserRoleEntity();
                userRoleEntity.setId(idGenerateHelper.nextId());
                userRoleEntity.setUserId(userEntity.getId());
                userRoleEntity.setRoleId(x.getId());
                return userRoleEntity;
            }).collect(Collectors.toList());
        }
        return Collections.emptyList();
    }

    @Override
    public int update(UserEntity userEntity) {
        userEntity.setUpdateTime(new Date());
        // 使用updateById方法更新实体
        return usermapper.updateById(userEntity);
    }

    @Override
    public int delete(Long id) {
        UserEntity userEntity = new UserEntity();
        userEntity.setId(id);

        userEntity.setIsDel(1);

        return usermapper.updateById(userEntity);
    }
    @Override
    public PageResultDTO<UserEntity> searchUsers(UserSearchDTO searchDTO) {
        // 创建分页对象
        IPage<UserEntity> page = new Page<>(searchDTO.getPage(), searchDTO.getSize());

        // 构建查询条件
        QueryWrapper<UserEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("is_del", 0); // 只查询未删除的用户

        // 添加模糊搜索条件
        if (searchDTO.getName() != null && !searchDTO.getName().trim().isEmpty()) {
            queryWrapper.like("user_name", searchDTO.getName().trim());
        }
//
//        if (searchDTO.getAge() != null) {
//            queryWrapper.eq("age", searchDTO.getAge());
//        }

        // 执行分页查询
        IPage<UserEntity> resultPage = usermapper.selectPage(page, queryWrapper);

        // 封装分页结果
        return new PageResultDTO<>(
                resultPage.getRecords(),
                resultPage.getTotal(),
                (int) resultPage.getCurrent(),
                (int) resultPage.getSize()
        );
    }

    @Override
    public TokenEntity login(AuthUserEntity authUserEntity) {
        try {
            String code = redisUtil.get(getCaptchaKey(authUserEntity.getUuid()));
            AssertUtil.hasLength(code, "该验证码不存在或者已失效");
            AssertUtil.isTrue(code.trim().equals(authUserEntity.getCode().trim()), "验证码错误");
            String decodePassword = passwordUtil.decodeRsaPassword(authUserEntity);
            System.out.println("decodePassword:"+decodePassword);
            System.out.println("authUserEntity.getPassword():"+authUserEntity.getPassword());
            UsernamePasswordAuthenticationToken authenticationToken =
                    new UsernamePasswordAuthenticationToken(authUserEntity.getUsername(), decodePassword);
            Authentication authentication = authenticationManagerBuilder.getObject().authenticate(authenticationToken);
            SecurityContextHolder.getContext().setAuthentication(authentication);
            String token = tokenHelper.generateToken((JwtUserEntity) (authentication.getPrincipal()));
            JwtUserEntity jwtUserEntity = (JwtUserEntity) (authentication.getPrincipal());
            redisUtil.del(getCaptchaKey(authUserEntity.getUuid()));
            return new TokenEntity(authUserEntity.getUsername(), token, jwtUserEntity.getRoles());
        } catch (Exception e) {
            log.info("登录失败：", e);
            throw new BusinessException(HttpStatus.FORBIDDEN.value(), " 账号或密码错误");
        }
    }


//    @Override
//    public TokenEntity login(AuthUserEntity authUserEntity) {
//        // 验证码校验
//        String code = redisUtil.get(getCaptchaKey(authUserEntity.getUuid()));
//        if (code == null || code.trim().length() == 0) {
//            throw new BusinessException(HttpStatus.FORBIDDEN.value(), "该验证码不存在或者已失效");
//        }
//        if (!code.trim().equals(authUserEntity.getCode().trim())) {
//            throw new BusinessException(HttpStatus.FORBIDDEN.value(), "验证码错误");
//        }
//
//        try {
//            String decodePassword = passwordUtil.decodeRsaPassword(authUserEntity);
//            UsernamePasswordAuthenticationToken authenticationToken =
//                    new UsernamePasswordAuthenticationToken(authUserEntity.getUsername(), decodePassword);
//            Authentication authentication = authenticationManagerBuilder.getObject().authenticate(authenticationToken);
//            SecurityContextHolder.getContext().setAuthentication(authentication);
//            String token = tokenHelper.generateToken((JwtUserEntity) (authentication.getPrincipal()));
//            redisUtil.del(getCaptchaKey(authUserEntity.getUuid()));
//            return new TokenEntity(authUserEntity.getUsername(), token);
//        } catch (BusinessException e) {
//            // 直接抛出业务异常，保持异常信息不变
//            throw e;
//        } catch (Exception e) {
//            log.info("登录失败：", e);
//            throw new BusinessException(HttpStatus.FORBIDDEN.value(), "用户名或密码错误");
//        }
//    }



    @Override
    public void logout(HttpServletRequest request) {
        String token = TokenUtil.getTokenForAuthorization(request);
        System.out.println( "token"+token);
        AssertUtil.hasLength(token, "Authorization不正确");
        tokenHelper.delToken(token);
    }


    @Override
    public CaptchaEntity getCode() {
        ArithmeticCaptcha captcha = new ArithmeticCaptcha(111, 36);
        // 几位数运算，默认是两位
        captcha.setLen(2);
        // 获取运算的结果
        String result = "";
        try {
            result = new Double(Double.parseDouble(captcha.text())).intValue() + "";
        } catch (Exception e) {
            result = captcha.text();
        }
        String uuid = "C" + IdUtil.simpleUUID();
        // 保存
        redisUtil.set(getCaptchaKey(uuid), result, captchaExpireSecond);
        return new CaptchaEntity(uuid, captcha.toBase64());
    }
    private String getCaptchaKey(String uuid) {
        return String.format("%s%s", CAPTCHA_PREFIX, uuid);
    }

    @Override
    public JwtUserEntity getUserInfo() {
        String currentUsername = tokenHelper.getCurrentUsername();
        return (JwtUserEntity) userDetailsService.loadUserByUsername(currentUsername);
    }
}
